package com.luboyan.CBillbill.advice;

import com.luboyan.CBillbill.exception.ConditionException;
import com.luboyan.CBillbill.util.Result;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

/**
 * ControllerAdvice注解这个类是为了那些声明（@ExceptionHandler,@InitBinder或@ModelAttribute注解修饰的）方法的类
 * 而提供的专业化的@Component，以提供多个Controller使用。是一种aop思想的实现，设置拦截规则，拦截器会拦截下来，就去做更细
 * 致的自定义
 *
 * 异常处理方法的执行流程
 * 当Spring MVC框架捕获到一个异常时，它会遍历所有的全局异常处理器，并根据@ExceptionHandler注解指定的异常类型来选择合适的处理方法。
 * 如果找到了匹配的处理方法，Spring MVC框架就会调用该方法来处理异常。
 * 在CommonGlobalExceptionAdvice类中，commonExceptionHandler方法是一个异常处理方法。
 * 它接收两个参数：HttpServletRequest request和Exception e。
 * 方法内部首先获取异常的消息内容，然后判断异常是否是ConditionException的实例。
 * 根据判断结果，方法会构造一个Result对象来封装响应的code码和消息内容，并将该对象作为HTTP响应正文返回给客户端。
 */
@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CommonGlobalExceptionAdvice {

    /**
     * 一个异常处理器,可以主动抛出自己设置的异常
     * 因为我们自己设置的Result返回类中会带一个code码，Exception是没有的，所以需要我们自己去拦截
     * 下来进行注入
     * @param request 从前端拿到的数据
     * @param e 捕获的异常
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result<String> commonExceptionHandler(HttpServletRequest request, Exception e){
        String msg = e.getMessage();
        if(e instanceof ConditionException){
            String code = ((ConditionException)e).getCode();
            return new Result<>(code, msg);
        }else{
            return new Result<>("500", msg);
        }
    }


}
